<?php
/**
 * Created by PhpStorm.
 * User: Rain
 * Date: 2020/5/16
 * Time: 13:44
 */

namespace app\admin\service\business\controllers\Access\Menu;


use app\admin\service\business\BaseControllerService;
use app\admin\service\business\controllers\Access\Interfaces\HandlerRoleModelInterface;
use app\admin\service\business\controllers\Access\Menu\Models\AdminMenuModel;
use think\facade\Db;

/**
 * Class AdminMenuService
 *
 * @property-read AdminMenuModel $model
 *
 * @package app\admin\service\business\controllers\Access\Menu
 */
class AdminMenuService extends BaseControllerService
{
    protected $rely = [
        'model' => AdminMenuModel::class,
    ];

    /**
     * 查询列表
     *
     * @param array $where
     * @return mixed
     */
    public function resList(array $where)
    {
        $list = handlerCateList($this->model->getList($where['key'] ?? [], [], false)->toArray(), 'parent_id');

        // 数据结构处理
        $list = $this->handlerMenuList($list);

        // 去除子节点
        array_walk($list, function (&$value) {
            unset($value['children']);
        });

        return array_values($list);
    }

    /**
     * 数据结构处理
     *
     * @param array $list
     * @return array
     */
    private function handlerMenuList(array $list)
    {
        $newList = [];

        foreach ($list as $k => $v) {
            array_push($newList, $v);

            if ($v['children']) $newList = array_merge($newList, $this->handlerMenuList($v['children']));
        }

        return $newList;
    }

    /**
     * 查询单条信息
     *
     * @param int $id
     * @return mixed
     */
    public function resFind(int $id)
    {
        $result = $this->model->getFind($id);

        // 拥有的权限
        $result->roleIds = implode(',', $result->roles->column('id'));

        // icon
        $result->code = $result->icon;
        $result->icon = json_encode([
            ['name' => arrConversion(config('icon.x-admin'), 'code')[$result->icon]['name'], 'value' => $result->icon]
        ]);

        return $result;
    }

    /**
     * 操作数据
     *
     * @param HandlerRoleModelInterface $handlerRoleModel
     * @param array $params
     * @param int $id
     * @return array
     */
    public function operating(HandlerRoleModelInterface $handlerRoleModel, array $params, int $id = 0): array
    {
        // 处理菜单
        if ($params['parent_id'] && !$this->model->getFind($params['parent_id'], ['id'])) return echoArr(500, '请选择父级分类');

        // 判断 title 是否重复
        if ($this->model->isUnique($params['title'], $params['parent_id'], $id)) return echoArr(500, '当前父分类下的标题重复');

        // 处理权限
        if (!$roleIds = $handlerRoleModel->getRoleIds(explode(',', $params['roles']))) return echoArr(500, '请选择权限');

        // 需操作的数据
        $data = [
            'title' => $params['title'],
            'icon' => $params['icon'],
            'uri' => $params['uri'],
            'parent_id' => $params['parent_id'],
            'description' => $params['description']
        ];


        // 开启事务
        Db::startTrans();

        try {
            // 执行数据更新
            if ($id) {
                $result = $this->model->edit($data, $id);
            } else {
                $result = $this->model->insert($data);
            }

            // 新增自增id
            if (!$id) $id = $result->id;

            // 更新角色权限
            $this->model->updateRole($id, $roleIds);

            Db::commit();
        } catch (\Exception $e) {
            Db::rollback();

            return echoArr(800);
        }

        return echoArr(200);
    }


    /**
     * 删除数据
     *
     * @param int $id
     * @return array
     */
    public function del(int $id): array
    {
        // 是否有子分类
        if ($this->model->isChildRen($id)) return echoArr(500, '当前分类下有子分类，请先移除');

        // 开启事务
        Db::startTrans();

        try {
            // 更新权限
            $this->model->updateRole($id, []);

            // 删除角色
            $this->model->delete($id);

            Db::commit();
        } catch (\Exception $exception) {
            Db::rollback();

            return echoArr(800);
        }

        return echoArr(200, '操作成功');
    }

    /**
     * 获取权限列表
     *
     * @param HandlerRoleModelInterface $handlerRoleModel
     * @return mixed
     */
    public function getRoleList(HandlerRoleModelInterface $handlerRoleModel)
    {
        return $handlerRoleModel->getRoleList()->toArray();
    }

    /**
     * 菜单列表（无限级）
     *
     * @param int $parentId 选中的父级id
     * @param int $id 当前菜单id
     * @return array
     */
    public function getMenuList(int $parentId = 0, int $id = 0)
    {
        $quoteIds = [];
        $list = handlerCateList($this->model->getList(['id' => $id], ['id', 'title' => 'name', 'parent_id'], false)->toArray(), 'parent_id', false, $quoteIds);

        // 重整结构
        array_walk($list, function (&$value) use ($quoteIds, $parentId) {
            $value['value'] = $value['id'];

            // 选中则为 selected
            if ($value['id'] == $parentId) $value['selected'] = true;

            unset($value['id']);
            unset($value['level']);
        });

        // 清除引用
        foreach ($quoteIds as $v) {
            unset($list[$v]);
        }

        // 不为顶级分类则清除
        foreach ($list as $k => $v) {
            unset($list[$k]['parent_id']);

            if ($v['parent_id'] != 0) unset($list[$k]);
        }

        // 添加顶级分类
        $topCate = !$parentId ? ['name' => '顶级分类', 'value' => 0, 'children' => [], 'selected' => true] : ['name' => '顶级分类', 'value' => 0, 'children' => []];
        array_unshift($list, $topCate);

        return array_values($list);
    }
}
